package com.nathan.crm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nathan.base.ResultInfo;
import com.nathan.crm.exceptions.NoLoginException;
import com.nathan.crm.exceptions.ParamsException;
import com.nathan.crm.interceptor.NoLoginInterceptor;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
    全局异常统一处理

    方法返回值：
        1、返回视图
        2、返回JSON数据
    如何判断方法的返回值:
        通过方法上是否声明ResponseBody注解
            如果声明了，则表示返回数据
            如果没声明，则表示返回视图
 */
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {

    /**
        异常处理方法
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

       //判断异常是否为未登录异常
        if (ex instanceof NoLoginException){
            //跳转到登录页面
            return new ModelAndView("redirect:/index");
        }

        //默认异常处理（返回视图）
        ModelAndView modelAndView = new ModelAndView("error");
        //设置异常信息
        modelAndView.addObject("code",500);
        modelAndView.addObject("msg","系统异常，请重试");

        //判断HandlerMethod
        if (handler instanceof HandlerMethod){
            //类型转换
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //获取方法声明上的@ReponseBody对象
            ResponseBody responseBody = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);

            //判断ResponseBody是否为空（为空，表示返回视图；不为空，表示返回数据）
            if (responseBody == null){
                /*
                    返回视图
                 */
                //判断异常类型
                if (ex instanceof ParamsException){
                    ParamsException p = (ParamsException) ex;
                    //设置异常信息
                    modelAndView.addObject("code",p.getCode());
                    modelAndView.addObject("msg",p.getMsg());
                }

                return modelAndView;
            }else {
                /*
                    返回数据
                 */
                //设置默认的异常处理
                ResultInfo resultInfo = new ResultInfo();
                resultInfo.setCode(500);
                resultInfo.setMsg("系统错误，请稍后再试...");

                //判断异常是否为自定义异常
                if (ex instanceof ParamsException){
                    ParamsException p = (ParamsException) ex;
                    resultInfo.setCode(p.getCode());
                    resultInfo.setMsg(p.getMsg());
                }

                //设置响应类型以及编码格式
                response.setContentType("application/json;charset=UTF-8");
                //得到字符输出流
                PrintWriter out = null;
                try {
                    out = response.getWriter();
                    //将需要返回的数据转换为json对象
                    String json = JSON.toJSONString(resultInfo);
                    //输出数据
                    out.write(json);
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    //关闭流
                    if (out != null) {
                        out.close();
                    }
                }

                return null;
            }
        }

        return modelAndView;
    }
}
